Skip to content

feat(support): withKeys and withoutKeys methods for manipulatesarray#2094

Merged
brendt merged 4 commits intotempestphp:3.xfrom
iamdadmin:3.x-with-without-manipulatesarray
Apr 1, 2026
Merged

feat(support): withKeys and withoutKeys methods for manipulatesarray#2094
brendt merged 4 commits intotempestphp:3.xfrom
iamdadmin:3.x-with-without-manipulatesarray

Conversation

@iamdadmin
Copy link
Copy Markdown
Contributor

@iamdadmin iamdadmin commented Mar 31, 2026

Suggested from #2092 - introduces convenience methods ->withKeys and ->withoutKeys for ManipulatesArray, and tests.

Usage examples from the test:

    public function test_with_keys(): void
    {
        $collection = arr([
            'first_name' => 'John',
            'last_name' => 'Doe',
            'age' => 42,
        ]);
        $current = $collection
            ->withKeys(['first_name', 'last_name'])
            ->toArray();
        $expected = [
            'first_name' => 'John',
            'last_name' => 'Doe',
        ];

        $this->assertSame($expected, $current);
    }

    public function test_without_keys(): void
    {
        $collection = arr([
            'first_name' => 'John',
            'last_name' => 'Doe',
            'age' => 42,
        ]);
        $current = $collection
            ->withoutKeys(['age'])
            ->toArray();
        $expected = [
            'first_name' => 'John',
            'last_name' => 'Doe',
        ];

        $this->assertSame($expected, $current);
    }

Copy link
Copy Markdown
Member

@innocenzi innocenzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the methods, but not the names; I don't think generic method names are helpful and I'd like to see more specific ones.

These are essentially "filter" methods, so maybe with should be an update to the existing filter where it accepts an array, and without should be a new reject method?

@iamdadmin
Copy link
Copy Markdown
Contributor Author

iamdadmin commented Mar 31, 2026

I like the methods, but not the names; I don't think generic method names are helpful and I'd like to see more specific ones.

These are essentially "filter" methods, so maybe with should be an update to the existing filter where it accepts an array, and without should be a new reject method?

Well, given that it’s using diffKeys and intersectKeys under the hood, how about withKeys and withoutKeys? Or alternatively onlyKeys and exceptKeys?

Filter I’m guessing already exists and will take a closure. Reject is fine but I think except or without fits it better?

Edit: yep, filter takes a closure, and the issue with having it accept either a closure or with functionality, is that a filter can be both positive, negative, and based on other criteria, where with is a positive filter only. So I suggest avoiding the clash with that and with array_filter as that implies that kind of functionality from it.

Edit 2: given the intent behind your suggestion and the possibly ambiguity of using with or without at all (especially as with is sometimes a reserved operator in programming languages), I refactored to onlyKeys and exceptKeys which I think makes it clear what it does, and what you need to pass (i.e. 'keys').

@iamdadmin iamdadmin changed the title feat(support): with and without methods for manipulatesarray feat(support): onlyKeys and exceptKeys methods for manipulatesarray Mar 31, 2026
@xHeaven
Copy link
Copy Markdown
Member

xHeaven commented Apr 1, 2026

Y'all are going to hate me, but I'd love to be able to pass Closures to these methods.

@iamdadmin
Copy link
Copy Markdown
Contributor Author

iamdadmin commented Apr 1, 2026

Y'all are going to hate me, but I'd love to be able to pass Closures to these methods.

I’d say that’s what the filter method is for. It takes a closure and performs whatever filter you want, negative, positive, or arbitrary logic.

@brendt
Copy link
Copy Markdown
Member

brendt commented Apr 1, 2026

I’d say that’s what the filter method is for. It takes a closure and performs whatever filter you want, negative, positive, or arbitrary logic.

Agree.

Naming is hard 😅 I think there should be proper symmetry:

  • with and without is the simplest, though a bit implicit that it works on keys
  • withKeys and withoutKeys is more explicit, but also more verbose
  • includeKeys and excludeKeys — just another idea
  • include and exclude — probably too generic

tbh my preference is with and without, since the parameter name will make it clear that we're talking about keys.

@iamdadmin
Copy link
Copy Markdown
Contributor Author

I think my two pennies here is that whatever first part is chosen, that Keys should still suffix, that's the convention in use elsewhere within the class for when it explicitly works with Keys instead of Values.

From a grammar perspective, the issue with "include" is it doesn't entirely communicate that it's an exclusive list, and in fairness, "with" also doesn't entirely communicate that it's an exclusive list. They both possibly imply "append" the values - whereas "only" clearly states that you're going to get "only" that back, which is the point of it.

In the context of removing certain keys and getting the remainder, "except", "exclude", "remove", "without" all work.

I did some searches and here's some more ideas that I think communicate "only" instead of "append":

  • withKeys / withoutKeys, possible slightly ambiguous as above
  • includeKeys / excludeKeys, possible slightly ambiguous as above
  • onlyKeys / exceptKeys, not clearly antonyms for each other (Laravel uses this)
  • pickKeys / dropKeys, drop is possibly ambiguous as it could imply it removes keys from the array, opposed to returning a copy, but used in JS space so has some precedence
  • keepKeys / removeKeys, remove is possibly ambiguous as it could imply it removes keys from the array, opposed to returning a copy
  • keepKeys / omitKeys, clearly indicates "only" on both, Go and some Python use this

Unrecommended ideas

  • Filter, already exists, accepts a closure
  • Pluck, already exists, accepts a single string and edits the array opposed to returning a copy
  • Pop, already exists, removes the last item from the array opposed to returning a copy

@brendt
Copy link
Copy Markdown
Member

brendt commented Apr 1, 2026

I then say withKeys / withoutKeys

@iamdadmin
Copy link
Copy Markdown
Contributor Author

I then say withKeys / withoutKeys

Refactored and clean qa locally, I imagine the checks will be along in a few :)

@iamdadmin iamdadmin changed the title feat(support): onlyKeys and exceptKeys methods for manipulatesarray feat(support): withKeys and withoutKeys methods for manipulatesarray Apr 1, 2026
@brendt brendt merged commit 61c0c3f into tempestphp:3.x Apr 1, 2026
76 checks passed
@brendt
Copy link
Copy Markdown
Member

brendt commented Apr 1, 2026

Perfect!

@iamdadmin iamdadmin deleted the 3.x-with-without-manipulatesarray branch April 1, 2026 11:15
iamdadmin added a commit to iamdadmin/tempest-framework that referenced this pull request Apr 1, 2026
@innocenzi
Copy link
Copy Markdown
Member

innocenzi commented Apr 1, 2026

Well, didn't have time to weight in again but withKeys implies to me that those keys would be added to the array, not that a copy of it with only those keys would be kept...

It's not the right name imo. It might be an unpopular opinion, but while stuff like "with" and "without" sound good in theory, they're hella confusing and I always end up having to look at what they actually do and compare it to other methods with similar generic names. I would really like it if we kept using explicit names 😔

There's also the issue of the names implying that the original array would be modified, which might not be the case depending on whether the instance is ImmutableArray or MutableArray

@shaffe-fr
Copy link
Copy Markdown
Contributor

I’m really glad this point was raised, as I share exactly the same concerns regarding the withKeys / withoutKeys naming.

The distinction between 'adding' and 'keeping' is a crucial one. To me, withKeys naturally feels like an append operation, whereas onlyKeys or keepKeys leaves no doubt that the result is an exclusive list. I also think the point about the ...Keys suffix is spot on.

I'm afraid that with/without might be just ambiguous enough to force developers to double-check the implementation, especially when it comes to whether the original array is modified or not.

Between the explicit options, I’d personally lean towards onlyKeys / exceptKeys. Since these terms are already used in Laravel, they have the advantage of being familiar to many while remaining perfectly clear about the end result.

@brendt
Copy link
Copy Markdown
Member

brendt commented Apr 2, 2026

Well we didn't tag this yet, so no harm done. I don't really agree with you, but I also don't really care too much about it, so I'm fine changing it. Feel free to send a PR @innocenzi or @shaffe-fr or @iamdadmin with a better name. onlyKeys and exceptKeys is fine

@iamdadmin
Copy link
Copy Markdown
Contributor Author

#2097 Enzo is on it!

iamdadmin added a commit to iamdadmin/tempest-framework that referenced this pull request Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants